﻿/*  
	------------------------------------------------------------------------
	 NQ Core Library
	
	 Homepage: http://www.awzhome.de/
	------------------------------------------------------------------------
	
	This Source Code Form is subject to the terms of the Mozilla Public
	License, v. 2.0. If a copy of the MPL was not distributed with this
	file, You can obtain one at http://mozilla.org/MPL/2.0/.
   
	The Original Code is code of NQ Core Library.

	The Initial Developer of the Original Code is Andreas Weizel.
	Portions created by the Initial Developer are
	Copyright (C) 2012 Andreas Weizel. All Rights Reserved.
	
	Contributor(s): (none)
	
	------------------------------------------------------------------------
*/

using System;

namespace AWZhome.NQ.Core.Fluent
{
	/// <summary>
	/// Wraps a "lazy created" list of service instances to be used
	/// with the NQ fluent interface.
	/// </summary>
	/// <typeparam name="T">Type of the service instances.</typeparam>
	public class LazyCreatedServiceListWrapper<T> : ServiceListWrapper<T>
	{
		protected string _listName = null;
		protected bool _includeMultiInstanceServices = true;
		protected bool _includeSingleInstanceServices = false;

		internal LazyCreatedServiceListWrapper(string listName)
		{
			_listName = listName;
		}

		/// <summary>
		/// Returns a service instance from the internal list.
		/// </summary>
		/// <param name="index">Index of the service instance to retrieve.</param>
		/// <returns>Service instance at the given index.</returns>
		public override T this[int index]
		{
			get
			{
				this.CreateInternalInstances();
				return _serviceInstances[index];
			}
		}

		/// <summary>
		/// Returns an array of the wrapped service instances.
		/// </summary>
		//[Obsolete("Please use Instances property instead.")]
		public override T[] To
		{
			get
			{
				this.CreateInternalInstances();
				return base.To;
			}
		}

		/// <summary>
		/// Returns an array of the wrapped service instances.
		/// </summary>
		public override T[] Instances
		{
			get
			{
				this.CreateInternalInstances();
				return base.To;
			}
		}

		/// <summary>
		/// Excludes multi-instance services into service instance creation
		/// from the AttachList.
		/// </summary>
		public LazyCreatedServiceListWrapper<T> WithoutMultiInstanceServices
		{
			get
			{
				_includeMultiInstanceServices = false;
				return this;
			}
		}

		/// <summary>
		/// Includes single-instance services into service instance creation
		/// from the AttachList.
		/// </summary>
		public LazyCreatedServiceListWrapper<T> WithSingleInstanceServices
		{
			get
			{
				_includeSingleInstanceServices = true;
				return this;
			}
		}

		/// <summary>
		/// Invokes (calls the invoke method of) all wrapped service instance.
		/// </summary>
		/// <returns>The instance of the wrapper.</returns>
		public override ServiceListWrapper<T> InvokeAll()
		{
			this.CreateInternalInstances();
			return base.InvokeAll();
		}

		/// <summary>
		/// Quits (calls the quit method of) all wrapped service instances.
		/// </summary>
		/// <returns>The instance of the wrapper.</returns>
		public override ServiceListWrapper<T> QuitAll()
		{
			this.CreateInternalInstances();
			return base.QuitAll();
		}

		/// <summary>
		/// Executes an expression on all wrapped service instances.
		/// </summary>
		/// <param name="expression">Expression to execute on every instance.</param>
		/// <returns>The instance of the wrapper.</returns>
		public override ServiceListWrapper<T> WithAll(Func<T, object> expression)
		{
			this.CreateInternalInstances();
			return base.WithAll(expression);
		}

		private void CreateInternalInstances()
		{
			if (_serviceInstances == null)
			{
				_serviceInstances =
					NQServiceManager.Instance.GetAttachedServices<T>(
						_listName, _includeMultiInstanceServices, _includeSingleInstanceServices
					);
			}
		}
	}
}
